import { ElMessage, ElMessageBox } from 'element-plus'
import { userLogout, adminLogout, isUserLoggedIn, isAdminLoggedIn } from '@/utils/auth'
import api from '@/utils/api'

/**
 * Token监控服务
 * 用于检测token失效和单点登录冲突
 */
class TokenMonitor {
  constructor() {
    this.checkInterval = null
    this.isChecking = false
    this.lastCheckTime = 0
    this.checkIntervalTime = 30000 // 30秒检查一次，更及时检测被踢掉的情况
    this.isMonitoring = false
    this.hasShownDialog = false // 防止重复弹窗
    this.visibilityChangeHandler = null // 存储事件处理器引用
  }

  /**
   * 开始监控token状态
   */
  startMonitoring() {
    if (this.isMonitoring) {
      return
    }

    this.isMonitoring = true
    this.hasShownDialog = false
    this.lastCheckTime = Date.now() // 初始化检查时间，避免立即触发
    console.log('🔍 开始监控token状态')

    // 设置定时检查（不立即检查，避免与登录后的其他请求冲突）
    this.checkInterval = setInterval(() => {
      this.checkTokenStatus()
    }, this.checkIntervalTime)

    // 监听页面可见性变化，当页面重新可见时检查token
    this.visibilityChangeHandler = () => {
      const timeSinceLastCheck = Date.now() - this.lastCheckTime
      console.log('📱 页面可见性变化，距离上次检查:', timeSinceLastCheck, 'ms')

      if (!document.hidden && timeSinceLastCheck > 300000) { // 增加到5分钟间隔，避免频繁检查
        console.log('🔍 触发token状态检查（页面可见性变化）')
        this.checkTokenStatus()
      } else if (!document.hidden) {
        console.log('⏭️ 跳过token检查，距离上次检查时间太短')
      }
    }
    document.addEventListener('visibilitychange', this.visibilityChangeHandler)
  }

  /**
   * 停止监控
   */
  stopMonitoring() {
    if (this.checkInterval) {
      clearInterval(this.checkInterval)
      this.checkInterval = null
    }

    // 移除页面可见性变化监听器
    if (this.visibilityChangeHandler) {
      document.removeEventListener('visibilitychange', this.visibilityChangeHandler)
      this.visibilityChangeHandler = null
    }

    this.isMonitoring = false
    this.hasShownDialog = false
    console.log('⏹️ 停止监控token状态')
  }

  /**
   * 检查token状态
   */
  async checkTokenStatus() {
    if (this.isChecking) {
      console.log('⏭️ Token检查已在进行中，跳过')
      return
    }

    this.isChecking = true
    this.lastCheckTime = Date.now()
    console.log('🔍 开始检查token状态...')

    try {
      // 检查用户token
      if (isUserLoggedIn()) {
        console.log('👤 检测到用户已登录，检查用户token')
        const userToken = localStorage.getItem('userToken')
        console.log('🔑 用户token:', userToken ? userToken.substring(0, 20) + '...' : 'null')
        await this.checkUserToken()
      } else {
        console.log('👤 用户未登录，跳过用户token检查')
      }

      // 检查管理员token
      if (isAdminLoggedIn()) {
        console.log('👨‍💼 检测到管理员已登录，检查管理员token')
        const adminToken = localStorage.getItem('adminToken')
        console.log('🔑 管理员token:', adminToken ? adminToken.substring(0, 20) + '...' : 'null')
        await this.checkAdminToken()
      } else {
        console.log('👨‍💼 管理员未登录，跳过管理员token检查')
      }

      console.log('✅ Token检查完成')
    } catch (error) {
      console.error('❌ Token检查失败:', error)
    } finally {
      this.isChecking = false
    }
  }

  /**
   * 检查用户token
   */
  async checkUserToken() {
    try {
      console.log('🔍 检查用户token状态...')
      // 使用获取用户会话列表的API来验证token（轻量级）
      const response = await api.get('/message/sessions')
      console.log('✅ Token检查响应:', response)

      // 修复：api.js返回完整的response对象，需要访问response.data.code
      const responseData = response.data
      if (responseData.code !== 200 && responseData.code !== '200') {
        console.log('❌ Token检查失败，响应码:', responseData.code)
        this.handleTokenInvalid('user', '您的账号已在其他设备登录，当前登录已失效')
      } else {
        console.log('✅ Token检查通过')
      }
    } catch (error) {
      console.log('❌ Token检查异常:', error)
      if (error.response?.status === 401) {
        console.log('❌ 401错误，token无效')
        this.handleTokenInvalid('user', '您的账号已在其他设备登录，当前登录已失效')
      } else {
        console.log('❌ 其他错误，不处理token失效')
      }
    }
  }

  /**
   * 检查管理员token
   */
  async checkAdminToken() {
    try {
      // 使用管理员中介申请列表API验证token（这个API确实存在）
      const response = await api.get('/admin/agent/list')

      // 修复：api.js返回完整的response对象，需要访问response.data.code
      const responseData = response.data
      if (responseData.code !== 200 && responseData.code !== '200') {
        this.handleTokenInvalid('admin', '您的管理员账号已在其他设备登录，当前登录已失效')
      }
    } catch (error) {
      if (error.response?.status === 401) {
        this.handleTokenInvalid('admin', '您的管理员账号已在其他设备登录，当前登录已失效')
      }
    }
  }

  /**
   * 处理token失效
   */
  async handleTokenInvalid(type, message) {
    // 防止重复弹窗
    if (this.hasShownDialog) {
      return
    }

    this.hasShownDialog = true
    this.stopMonitoring()

    try {
      await ElMessageBox.confirm(
        `${message}，请重新登录`,
        '登录状态异常',
        {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning',
          closeOnClickModal: false,
          closeOnPressEscape: false
        }
      )

      // 用户确认后执行登出
      this.performLogout(type)
    } catch {
      // 用户取消，强制登出
      this.performLogout(type)
    }
  }

  /**
   * 执行登出操作
   */
  performLogout(type) {
    if (type === 'admin') {
      adminLogout()
      window.location.href = '/admin-login'
    } else {
      userLogout()
      window.location.href = '/login'
    }
  }

  /**
   * 手动触发token检查
   */
  forceCheck() {
    this.checkTokenStatus()
  }

  /**
   * 检查是否需要立即验证token（在关键操作前调用）
   */
  async checkBeforeImportantAction() {
    const timeSinceLastCheck = Date.now() - this.lastCheckTime
    // 如果距离上次检查超过30秒，立即检查一次
    if (timeSinceLastCheck > 30000) {
      console.log('🔍 关键操作前检查token状态')
      await this.checkTokenStatus()
    }
  }
}

// 创建全局实例
const tokenMonitor = new TokenMonitor()

export default tokenMonitor
